home *** CD-ROM | disk | FTP | other *** search
/ Technotools / Technotools (Chestnut CD-ROM)(1993).ISO / lang_c / cug187 / crc.c < prev    next >
Text File  |  1985-12-30  |  4KB  |  100 lines

  1. /*@****************************************************************************
  2. * @                                                                           *
  3. * @             Cyclic Redundancy Check (CRC) functions                       *
  4. * @                                                                           *
  5. **@***************************************************************************/
  6.  
  7. /*@
  8. * @ crc_clear:
  9. * @ This function clears the CRC to zero. It should be called prior to
  10. * @    the start of the processing of a block for both received messages,
  11. * @    and messages to be transmitted.
  12. * @
  13. * @    Calling sequence:
  14. * @
  15. * @    short crc;
  16. * @    crc = crc_clear();
  17. */
  18. short crc_clear()
  19. {
  20.     return(0);
  21. }
  22. /*@
  23. * @ crc_update:
  24. * @    this function must be called once for each character which is
  25. * @    to be included in the CRC for messages to be transmitted.
  26. * @    This function is called once for each character which is included
  27. * @    in the CRC of a received message, AND once for each of the two CRC
  28. * @    characters at the end of the received message. If the resulting
  29. * @    CRC is zero, then the message has been correctly received.
  30. * @
  31. * @ Calling sequence:
  32. * @
  33. * @    crc = crc_update(crc,next_char);
  34. */
  35. short crc_update(crc,crc_char)
  36. short crc;
  37. char crc_char;
  38. {
  39.     long x;
  40.     short i;
  41.  
  42. /* "x" will contain the character to be processed in bits 0-7 and the CRC    */
  43. /* in bits 8-23. Bit 24 will be used to test for overflow, and then cleared  */
  44. /* to prevent the sign bit of "x" from being set to 1. Bits 25-31 are not    */
  45. /* used. ("x" is treated as though it is a 32 bit register).                 */
  46.     x = ((long)crc << 8) + crc_char;    /* Get the CRC and the character */
  47.  
  48. /* Repeat the following loop 8 times (for the 8 bits of the character).      */
  49.     for(i = 0;i < 8;i++)
  50.     {
  51.  
  52. /* Shift the high-order bit of the character into the low-order bit of the   */
  53. /* CRC, and shift the high-order bit of the CRC into bit 24.                 */
  54.         x = x << 1;                        /* Shift "x" left one bit */
  55.  
  56. /* Test to see if the old high-order bit of the CRC was a 1.                 */
  57.         if(x & 0x01000000)                     /* Test bit 24 of "x" */
  58.  
  59. /* If the old high-order bit of the CRC was a 1, exclusive-or it with a one  */
  60. /* to set it to 0, and exclusive-or the CRC with hex 1021 to produce the     */
  61. /* CCITT-recommended CRC generator of: X**16 + X**12 + X**5 + 1. To produce  */
  62. /* the CRC generator of: X**16 + X**15 + X**2 + 1, change the constant from  */
  63. /* 0x01102100 to 0x01800500. This will exclusive-or the CRC with hex 8005    */
  64. /* and produce the same CRC that IBM uses for their synchronous transmission */
  65. /* protocols.                                                                */
  66.             x = x ^ 0x01102100;     /* Exclusive-or "x" with a...*/
  67.                                               /* ...constant of hex 01102100 */
  68. /* And repeat 8 times.                                                       */
  69.     }                                               /* End of "for" loop */
  70.  
  71. /* Return the CRC as the 16 low-order bits of this function's value.         */
  72.     return(((x & 0x00ffff00) >> 8)); /* AND off the unneeded bits and... */
  73.                                   /* ...shift the result 8 bits to the right */
  74.  
  75. }
  76. /*
  77. * @ crc_finish:
  78. * @    This function must be called once after all the characters in a block
  79. * @    have been processed for a message which is to be TRANSMITTED. It
  80. * @    returns the calculated CRC bytes, which should be transmitted as the
  81. * @    two characters following the block. The first of these 2 bytes
  82. * @    must be taken from the high-order byte of the CRC, and the second
  83. * @    must be taken from the low-order byte of the CRC. This routine is NOT
  84. * @    called for a message which has been RECEIVED.
  85. * @
  86. * @ Calling sequence:
  87. * @
  88. * @    crc = crc_finish(crc);
  89. */
  90. short crc_finish(crc)
  91. short crc;
  92. {
  93. /* Call crc_update twice, passing it a character of hex 00 each time, to     */
  94. /* flush out the last 16 bits from the CRC calculation, and return the       */
  95. /* result as the value of this function.                                     */
  96.     return(crc_update(crc_update(crc,'\0'),'\0'));
  97.  
  98. }
  99.  
  100.